package com.burst.reptile.modular.web.service.impl;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.burst.reptile.common.exception.CustomException;
import com.burst.reptile.common.utils.ToolUtil;
import com.burst.reptile.modular.web.entity.ZpBanner;
import com.burst.reptile.modular.web.form.SortForm;
import com.burst.reptile.modular.web.mapper.ZpBannerMapper;
import com.burst.reptile.modular.web.service.IZpBannerService;

import cn.hutool.core.util.StrUtil;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wujin
 * @since 2020-06-15
 */
@Service
public class ZpBannerServiceImpl extends ServiceImpl<ZpBannerMapper, ZpBanner> implements IZpBannerService {

	@Override
	public List<ZpBanner> listAll() {
		return this.list(new QueryWrapper<ZpBanner>().orderByAsc("banner_sort"));
	}
	
	@Override
	public List<ZpBanner> listShowAll() {
		return this.list(new QueryWrapper<ZpBanner>().eq("banner_status", "0").orderByAsc("banner_sort"));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void add(ZpBanner banner) {
		Integer bannerSort = banner.getBannerSort();
		String bannerHref = banner.getBannerHref();
		Integer sort = bannerSort == null || bannerSort <= 0 ? 1 : bannerSort;
		if(StrUtil.isEmpty(bannerHref)) {
			banner.setBannerHref("javascript:;");
		}
		// 获取所有轮播图
		List<ZpBanner> list = this.list(new QueryWrapper<ZpBanner>()
				.select("banner_id", "banner_sort")
				.ge("banner_sort", sort)
				.orderByAsc("banner_sort"));
		
		//重新排序
		if(ToolUtil.isNotEmpty(list)) {
			int size = list.size();
			for (int i = 0; i < size; i++) {
				ZpBanner dbbanner = list.get(i);
				dbbanner.setBannerSort(sort + i + 1);
				boolean updateById = this.updateById(dbbanner);
				if(!updateById) {
					throw new CustomException("保存失败");
				}
			}
		}else {
			ZpBanner one = this.getOne(new QueryWrapper<ZpBanner>().select("MAX(banner_sort) as bannerSort"));
			if(one != null) {
				if(sort > one.getBannerSort()) {
					sort = one.getBannerSort() + 1; 
				}
			}else {
				sort = 1;
			}
		}
		banner.setBannerSort(sort);
		boolean save = this.save(banner);
		if(!save) {
			throw new CustomException("保存失败");
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void edit(ZpBanner banner) {
		Integer bannerId = banner.getBannerId();
		String bannerHref = banner.getBannerHref();
		if(StrUtil.isEmpty(bannerHref)) {
			banner.setBannerHref("javascript:;");
		}
		if(ToolUtil.isEmpty(bannerId)) {
			throw new CustomException("资源不存在");
		}
		Integer bannerSort = banner.getBannerSort();
		Integer sort = bannerSort == null || bannerSort <= 0 ? 1 : bannerSort;
		ZpBanner byId = this.getById(bannerId);
		if(byId == null) {
			throw new CustomException("资源不存在");
		}
	
		Integer bannSort = byId.getBannerSort();
		if(bannSort != sort) {
			if(sort < bannSort) {
				// 获取高部分数据
				List<ZpBanner> list = this.list(new QueryWrapper<ZpBanner>()
						.select("banner_id", "banner_sort")
						.lt("banner_sort", bannSort)
						.ge("banner_sort", sort)
						.orderByAsc("banner_sort"));
				
				if(ToolUtil.isNotEmpty(list)) {
					int size = list.size();
					for (int i = 0; i < size; i++) {
						ZpBanner dbbanner = list.get(i);
						if(i == 0) {
							Integer orderWeight2 = dbbanner.getBannerSort();
							if(sort < orderWeight2) { // 说明设置比第一个还小
								sort = orderWeight2;
							}
						}
						dbbanner.setBannerSort(sort + i + 1);
						boolean updateById = this.updateById(dbbanner);
						if(!updateById) {
							throw new CustomException("排序失败");
						}
					}
				}else { //为空说明设置的就是第一位
					sort = 1;
				}
			}else if(sort > bannSort) { // 排序靠后了，则排序的这条数据往后的数据到指定排序的位置 左开右闭范围的数据向前移一位
				List<ZpBanner> list = this.list(new QueryWrapper<ZpBanner>()
						.select("banner_id", "banner_sort")
						.gt("banner_sort", bannSort)
						.le("banner_sort", sort)
						.orderByDesc("banner_sort"));
				
				if(ToolUtil.isNotEmpty(list)) {
					int size = list.size();
					for (int i = 0; i < size; i++) {
						ZpBanner dbbanner = list.get(i);
						if(i == 0) {
							Integer orderWeight2 = dbbanner.getBannerSort();
							if(sort > orderWeight2) { //设置的比最后一个还要大
								sort = orderWeight2;
							}
						}
						dbbanner.setBannerSort(sort - (i + 1));
						boolean updateById = this.updateById(dbbanner);
						if(!updateById) {
							throw new CustomException("排序失败");
						}
					}
				}else { // 为空说明设置的本身就是最后以为
					sort = bannSort;
				}
			}
		}
		banner.setBannerSort(sort);
		boolean updateById = this.updateById(banner);
		if(!updateById) {
			throw new CustomException("更新失败");
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(String id) {
		ZpBanner byId = this.getById(id);
		if(byId == null) {
			throw new CustomException("资源不存在");
		}
		boolean removeById = this.removeById(id);
		if(!removeById) {
			throw new CustomException("删除失败");
		}
		// 重新排序
		List<ZpBanner> list = this.list(new QueryWrapper<ZpBanner>()
				.select("banner_id", "banner_sort")
				.orderByAsc("banner_sort"));
		if(ToolUtil.isNotEmpty(list)) {
			for (int i = 0; i < list.size(); i++) {
				ZpBanner zpBanner = list.get(i);
				zpBanner.setBannerSort(i + 1);
				this.updateById(zpBanner);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sort(SortForm sortData) {
		Integer id = sortData.getId();
		Integer bannerSort = sortData.getSort();
		Integer sort = bannerSort == null || bannerSort <= 0 ? 1 : bannerSort;
		ZpBanner byId = this.getById(id);
		if(byId == null) {
			throw new CustomException("资源不存在");
		}
		Integer bannSort = byId.getBannerSort();
		if(sort == bannSort) {
			return;
		}
		if(sort < bannSort) {
			// 获取高部分数据
			List<ZpBanner> list = this.list(new QueryWrapper<ZpBanner>()
					.select("banner_id", "banner_sort")
					.lt("banner_sort", bannSort)
					.ge("banner_sort", sort)
					.orderByAsc("banner_sort"));
			
			if(ToolUtil.isNotEmpty(list)) {
				int size = list.size();
				for (int i = 0; i < size; i++) {
					ZpBanner dbbanner = list.get(i);
					if(i == 0) {
						Integer orderWeight2 = dbbanner.getBannerSort();
						if(sort < orderWeight2) { // 说明设置比第一个还小
							sort = 1;
						}
					}
					dbbanner.setBannerSort(sort + i + 1);
					boolean updateById = this.updateById(dbbanner);
					if(!updateById) {
						throw new CustomException("排序失败");
					}
				}
			}else { //为空说明设置的就是第一位
				sort = 1;
			}
		}else if(sort > bannSort) { // 排序靠后了，则排序的这条数据往后的数据到指定排序的位置 左开右闭范围的数据向前移一位
			List<ZpBanner> list = this.list(new QueryWrapper<ZpBanner>()
					.select("banner_id", "banner_sort")
					.gt("banner_sort", bannSort)
					.le("banner_sort", sort)
					.orderByDesc("banner_sort"));
			
			if(ToolUtil.isNotEmpty(list)) {
				int size = list.size();
				for (int i = 0; i < size; i++) {
					ZpBanner dbbanner = list.get(i);
					int uso = sort - (i + 1);
					if(i == 0) {
						Integer orderWeight2 = dbbanner.getBannerSort();
						if(sort > orderWeight2) { //设置的比最后一个还要大
							sort = orderWeight2;
							uso = orderWeight2 - (i + 1);
						}
					}
					dbbanner.setBannerSort(uso);
					boolean updateById = this.updateById(dbbanner);
					if(!updateById) {
						throw new CustomException("排序失败");
					}
				}
			}else { // 为空说明设置的本身就是最后以为
				sort = bannSort;
			}
		}
		byId.setBannerSort(sort);
		boolean updateById = this.updateById(byId);
		if(!updateById) {
			throw new CustomException("排序失败");
		}
	}

	@Override
	public void changeStatus(ZpBanner banner) {
		String bannerStatus = banner.getBannerStatus();
		int count = this.count(new QueryWrapper<ZpBanner>().eq("banner_status", "0"));
		if(StrUtil.equals("1", bannerStatus)) {
			if(count == 1) {
				throw new CustomException("至少需要显示一个");
			}
		}else {
			if(count == 5) {
				throw new CustomException("最多显示5个");
			}
		}
		this.update(banner, new UpdateWrapper<ZpBanner>().eq("banner_id", banner.getBannerId()));
	}

}
